/*
 * Copyright (C) 2013 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { Route } from '../Route'

/**
 * A blacklist of failed routes to avoid when creating a new connection to a target address. This is
 * used so that OkHttp can learn from its mistakes: if there was a failure attempting to connect to
 * a specific IP address or proxy server, that failure is remembered and alternate routes are
 * preferred.
 */
export class RouteDatabase {
  // 使用 Map 以 route 的字符串表示作为 key，解决 Set 对象引用比较问题
  private failedRoutes: Map<string, Route> = new Map<string, Route>()

  /** 生成 Route 的唯一标识符 */
  private routeKey(route: Route): string {
    return `${route.address.url.toString()}|${route.proxy.toString()}|${route.socketAddress.toString()}`
  }

  /** Records a failure connecting to [failedRoute]. */
  failed(failedRoute: Route) {
    this.failedRoutes.set(this.routeKey(failedRoute), failedRoute)
  }

  /** Records success connecting to [route]. */
  connected(route: Route) {
    this.failedRoutes.delete(this.routeKey(route))
  }

  /** Returns true if [route] has failed recently and should be avoided. */
  shouldPostpone(route: Route): boolean {
    return this.failedRoutes.has(this.routeKey(route))
  }
}
